﻿/*************************************************************************************
* 运行库版本：	4.0.30319.18408
* 类  名  称：	HikvisionCamera
* 命 名 空间：	FutureTech.Hardware.Camera.Hikvision
* 文  件  名：	HikvisionCamera
* 创 建 时间：	2014/3/23 19:59:23
* 作      者：	帅红  shuaihong617@qq.com
* 说      明：
* 修 改 时间：
* 修  改  人：
*************************************************************************************/

using System;

namespace FutureTech.Hardware.Camera.Hikvision
{
        public class HikvisionCamera : FtCamera
        {
                public HikvisionCamera(string name, int horizontalResolution, int verticalResolution, string ipAddress)
                        : base(name, horizontalResolution, verticalResolution, BitsWide.Bits32, true)
                {
                        IpAddress = ipAddress;

                        clientInfo = new HKNetSDK.NET_DVR_CLIENTINFO
                                {
                                        lChannel = 1,
                                        lLinkMode = 0x0000,
                                        sMultiCastIP = "",
                                        hPlayWnd = IntPtr.Zero
                                };

                        UserPtr = new IntPtr();

                        realDataSnapCallBack = RealDataSnapCallBack;
                }

                #region 属性

                /// <summary>
                ///         IP地址
                /// </summary>
                public string IpAddress { get; private set; }

                /// <summary>
                ///         登陆端口
                /// </summary>
                public const int LoginPort = 8000;

                /// <summary>
                ///         用户名称
                /// </summary>
                public const string LoginName = "admin";

                /// <summary>
                ///         登陆密码
                /// </summary>
                public const string Password = "12345";

                /// <summary>
                ///         设备信息结构体
                /// </summary>
                private HKNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo;

                /// <summary>
                ///         客户端信息结构体
                /// </summary>
                private HKNetSDK.NET_DVR_CLIENTINFO clientInfo;

                /// <summary>
                ///         实时数据回调
                /// </summary>
                private readonly HKNetSDK.REALDATACALLBACK realDataSnapCallBack;

                /// <summary>
                ///         播放句柄
                /// </summary>
                public int RealHandle { get; private set; }

                /// <summary>
                ///         登陆用户标识
                /// </summary>
                public int UserId { get; private set; }

                /// <summary>
                ///         用户指针
                /// </summary>
                public IntPtr UserPtr { get; private set; }

                /// <summary>
                ///         播放通道端口号
                /// </summary>
                public int PlayPort;

                #region SDK环境

                public static bool IsSdkSuccess { get; private set; }

                public static string SdkFailMessage { get; protected set; }

                #endregion

                #region 故障信息

                public bool IsLoginSuccess { get; protected set; }

                public bool IsStartPlaySuccess { get; protected set; }

                public bool IsSnapSuccess { get; protected set; }

                public bool IsStopPlaySuccess { get; protected set; }

                public bool IsLogoutSuccess { get; protected set; }

                public string FailMessage { get; protected set; }

                #endregion

                #endregion

                #region 方法

                #region 环境

                public static void InitializeSDK()
                {
                        IsSdkSuccess = HKNetSDK.NET_DVR_Init();
                        if (!IsSdkSuccess)
                        {
                                SdkFailMessage = "环境初始化失败，错误代码" + HKNetSDK.NET_DVR_GetLastError().ToString();
                                throw new InvalidOperationException(SdkFailMessage);
                        }
                }

                public static void UnInitializeSDK()
                {
                        if (IsSdkSuccess)
                        {
                                HKNetSDK.NET_DVR_Cleanup();
                        }
                }

                #endregion

                #region 图像采集

                public override void Open()
                {
                        HKNetSDK.NET_DVR_SetConnectTime(15000,3);
                        HKNetSDK.NET_DVR_SetReconnect(1000, 1);

                        IsLoginSuccess = false;
                        for (int i = 0; i < 10; i++)
                        {
                                UserId = HKNetSDK.NET_DVR_Login_V30(IpAddress, LoginPort, LoginName, Password,
                                                                    ref deviceInfo);
                                if (UserId != -1)
                                {
                                        IsLoginSuccess = true;
                                        break;
                                }
                        }

                        if (!IsLoginSuccess)
                        {
                                FailMessage = "摄像机登陆失败，错误代码" + HKNetSDK.NET_DVR_GetLastError().ToString();
                                OnOpenFailed(new MessageEventArgs(FailMessage));

                                throw new InvalidOperationException(FailMessage);
                        }

                        //UserId = HKNetSDK.NET_DVR_Login_V30(IpAddress, LoginPort, LoginName, Password, ref deviceInfo);
                        //if (UserId == -1)
                        //{
                        //    IsLoginSuccess = false;
                        //    FailMessage = "摄像机登陆失败，错误代码" + HKNetSDK.NET_DVR_GetLastError().ToString();
                        //    throw new InvalidOperationException(FailMessage);
                        //}
                }

                public override void StartSnap()
                {
                        RealHandle = HKNetSDK.NET_DVR_RealPlay_V30(UserId, ref clientInfo, realDataSnapCallBack, UserPtr,
                                                                   1);
                        if (RealHandle == -1)
                        {
                                IsStartPlaySuccess = false;
                                FailMessage = "摄像机启动播放失败，错误代码" + HKNetSDK.NET_DVR_GetLastError().ToString();
                                throw new InvalidOperationException(FailMessage);
                        }
                        HKNetSDK.NET_DVR_SetPlayerBufNumber(RealHandle, 4);
                }

                public void RealDataSnapCallBack(Int32 lRealHandle, uint dwDataType, ref byte pBuffer,
                                                 uint dwBufSize,
                                                 IntPtr pUser)
                {
                        bool success;
                        switch (dwDataType)
                        {
                                case HKNetSDK.NET_DVR_SYSHEAD: // 系统头
                                        success = HKPlaySDK.PlayM4_GetPort(ref PlayPort);
                                        //if (!success)
                                        //{
                                        //        IsStartPlaySuccess = false;
                                        //        FailMessage = "获取播放通道失败，错误信息：代码" +
                                        //                     HKPlaySDK.PlayM4_GetLastError(PlayPort);
                                        //}

                                        if (dwBufSize > 0)
                                        {
                                                if (
                                                        !HKPlaySDK.PlayM4_SetStreamOpenMode(PlayPort,
                                                                                            HKPlaySDK.STREAME_REALTIME))
                                                {
                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "设置采集数据流打开模式失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);
                                                        //return;
                                                }

                                                if (
                                                        !HKPlaySDK.PlayM4_OpenStream(PlayPort, ref pBuffer, dwBufSize,
                                                                                     (uint) (SnapBufferBytesCount*2)))
                                                {
                                                        PlayPort = -1;

                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "打开采集数据流失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);
                                                        //return;
                                                }

                                                if (!HKPlaySDK.PlayM4_SetDisplayBuf(PlayPort, 5))
                                                {
                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "实时播放缓冲区失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);

                                                        //return;
                                                }


                                                if (!HKPlaySDK.PlayM4_SetOverlayMode(PlayPort, 0, 0 /* COLORREF(0)*/))
                                                {
                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "设置采集模式失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);

                                                        //return;
                                                }

                                                if (!HKPlaySDK.PlayM4_Play(PlayPort, IntPtr.Zero))
                                                {
                                                        PlayPort = -1;
                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "实时数据播放失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);
                                                }
                                        }
                                        break;

                                case HKNetSDK.NET_DVR_STREAMDATA: // video stream data
                                        if (dwBufSize > 0 && PlayPort != -1)
                                        {
                                                if (!HKPlaySDK.PlayM4_InputData(PlayPort, ref pBuffer, dwBufSize))
                                                {
                                                        //IsStartPlaySuccess = false;
                                                        //FailMessage = "实时数据输入失败，错误信息：代码" +
                                                        //             HKPlaySDK.PlayM4_GetLastError(PlayPort);
                                                }
                                        }
                                        break;

                                default:
                                        break;
                        }
                }

                public override void Snap()
                {
                        uint snapBytesCount = 0;

                        IsSnapSuccess = HKPlaySDK.PlayM4_GetBMP(PlayPort, SnapBufferPtr, (uint) SnapBufferBytesCount,
                                                                ref snapBytesCount);
                        if (!IsSnapSuccess)
                        {
                                IsLoginSuccess = false;
                                FailMessage = "采集图像失败，错误信息：代码：" + HKPlaySDK.PlayM4_GetLastError(PlayPort);

                                //throw new InvalidOperationException(FailMessage);

                               
                        }
                        else
                        {
                                OnSnapSuccessed(new MessageEventArgs(string.Empty));
                        }


                        
                }


                public override void StopSnap()
                {
                        if (!IsStartPlaySuccess)
                        {
                                return;
                        }

                        if (RealHandle < 0)
                        {
                                IsStopPlaySuccess = false;
                                FailMessage = "摄像机停止播放失败，错误信息：实时播放句柄为" + RealHandle;
                                return;
                        }

                        bool success = HKNetSDK.NET_DVR_StopRealPlay(RealHandle);
                        if (!success)
                        {
                                IsStopPlaySuccess = false;
                                FailMessage = "摄像机停止播放失败，错误信息：代码" + HKNetSDK.NET_DVR_GetLastError();
                                return;
                        }

                        IsStopPlaySuccess = true;
                }

                public override void Close()
                {
                        //if (!IsStopPlaySuccess)
                        //{
                        //        return;
                        //}

                        //if (UserId < 0)
                        //{
                        //        IsLogoutSuccess = false;
                        //        FailMessage = "摄像机注销失败，错误信息：用户Id为" + UserId;
                        //        return;
                        //}

                        bool success = HKNetSDK.NET_DVR_Logout_V30(UserId);
                        if (!success)
                        {
                                IsLogoutSuccess = false;
                                FailMessage = "摄像机注销失败，错误信息：代码" + HKNetSDK.NET_DVR_GetLastError().ToString();
                                return;
                        }

                        IsLogoutSuccess = true;
                }

                #endregion

                #region 事件

                protected override void OnOpenFailed(MessageEventArgs e)
                {
                        base.OnOpenFailed(e);
                }

                protected override void OnSnapSuccessed(MessageEventArgs e)
                {
                        base.OnSnapSuccessed(e);
                }

                #endregion

                #endregion
        }
}
